<?php
/**
 * (jobs) (JP)备货品类/sku预估
 */
namespace App\Jobs\Stocking;

use App\Models\Basics\SysArea;
use App\Models\Basics\SysICountry;
use App\Models\Basics\SysPlat;
use App\Models\Product\ProductSku;
use App\Models\SsBasic\AreaClassifyEstimate;
use App\Models\SsBasic\AreaSkuEstimate;
use App\Models\SsBasic\JpClassifyEstimate;
use App\Models\SsBasic\JpSkuEstimate;
use App\Models\SsBasic\JpStockingSku;
use App\Models\SsBasic\JpStockingSkuRatio;
use App\Models\Stocking\StockingSku;
use App\Models\Stocking\StockingSkuRatio;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class JpSkuRatioJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $ratio;

    /**
     * SkuRatio constructor.
     * @param $ratio
     */
    public function __construct($ratio)
    {
        $this->ratio = $ratio;
    }

    /**
     * Execute the job.
     * @return void
     */
    public function handle()
    {
        $this->exeFillData($this->ratio);
    }

    private function exeFillData($ratio){

        $areaId = SysArea::AREA_JP; //JP站点
        $aseKey = [];
        $arr = [];
        $skuKey = [];
        $classifyKey = [];

        //1. 根据比例，更新JPsku预估，同步更新JP备货sku表里的预估
        //更新,JPsku预估、JP备货sku及相关信息
        foreach ($ratio as $_ratio){
            list($platId,$pSkuId) = explode('_',$_ratio->area_psku);
            if(!array_key_exists($pSkuId,$arr)){
                $__classifyId = ProductSku::getValueById($pSkuId,'classify_id');
                $arr[$pSkuId] = $__classifyId ?: 0;
            }
            $_classifyId = $arr[$pSkuId];
            if(!$_classifyId){
                continue;
            }
            //因为对应的JPsku的比例有更新，所以找到对应的JP品类预估用于修改JPsku的预估
            $_key = $platId.'_'.$_classifyId;
            if(!in_array($_key,$aseKey)){
                $aseKey[] = $_key;
            }
            //因为更新了JPsku比例,所以JPsku的预估会变化，导致汇总到JP站点sku的预估也会变化
            if(!array_key_exists($pSkuId,$skuKey)){
                $skuKey[$pSkuId] = $_classifyId;
            }
            //因为更新了JPsku比例,所以JPsku的预估会变化，使得汇总到JP站点sku的预估也会变化，导致汇总到站点SKU的预估也会变化
            if(!in_array($_classifyId,$classifyKey)){
                $classifyKey[] = $_classifyId;
            }
        }

        foreach ($aseKey as $_aseKey){
            list($platId,$classifyId) = explode('_',$_aseKey);

            $classifyEstimate = JpClassifyEstimate::query()
                ->where('plat_id',$platId)
                ->where('classify_id',$classifyId)
                ->first();
            if(!$classifyEstimate) continue;

            //JP备货sku
            $stockingSkus = JpStockingSku::query()
                ->where('plat_id',$platId)
                ->whereHas('sku',function ($query) use ($classifyId){
                    $query->where('classify_id',$classifyId);
                })
                ->get();
            foreach ($stockingSkus as $stockingSku){
                $apKey = $platId.'_'.$stockingSku->psku_id;
                //sku销售比例
                $ratio = JpStockingSkuRatio::getRatio($apKey);
                //JPsku预估 (JPsku预估 = sku比例 * JP品类预估)
                $skuEstimate = JpSkuEstimate::query()->firstOrNew(['area_psku' => $apKey]);
                for($i = 0;$i < AreaSkuEstimate::ESTIMATE_NUM;$i++){
                    $estimateNum = intval(round($classifyEstimate->{'estimate_num'.$i} * $ratio));
                    $stockingSku->{'estimate_num'.$i} = $estimateNum;
                    $skuEstimate->{'estimate_num'.$i} = $estimateNum;
                }
                $stockingSku->save();
                $skuEstimate->save();
                $stockingSku->over_stock = JpStockingSku::getOverStock($stockingSku);
                $stockingSku->over_stock_value = JpStockingSku::getOverStockValue($stockingSku->over_stock,$stockingSku->unit_price);
                $stockingSku->save();
            }
        }
        sleep(5);

        /*******更新JP站点SKU比例、JP站点SKU预估start*********/
        //更新,JP_品类
        foreach ($classifyKey as $classifyId){
            $classifyEstimateSum = JpClassifyEstimate::query()->selectRaw(getQueryEstimateStr())->where('classify_id', $classifyId)->first();
            $areaClassifyEstimate = AreaClassifyEstimate::query()->firstOrNew(['area_id' => $areaId, 'classify_id' => $classifyId]);
            if(!$areaClassifyEstimate) continue;
            for($i = 0; $i < AreaSkuEstimate::ESTIMATE_NUM; $i++){
                $areaClassifyEstimate->{'estimate_num'.$i} = $classifyEstimateSum->{'estimate_num'.$i};
            }
            $areaClassifyEstimate->save();
        }

        //2. 将JPsku预估汇总到JP站点sku预估
        //更新,JP_产品
        foreach ($skuKey as $_skuId => $classifyId){
            if(!$classifyId) continue;

            $areaPsku = $areaId.'_'.$_skuId; //唯一键标识(JP)

            //JP备货平台
            $platPskus = [];
            foreach (SysPlat::$_jpStockPlatformId as $platId){
                $platPskus[] = $platId.'_'.$_skuId;
            }
            //JPsku预估 (JP平台sku预估汇总 === JP站点sku预估总量)
            $skuEstimateSum = JpSkuEstimate::query()
                ->selectRaw(getQueryEstimateStr())
                ->whereIn('area_psku', $platPskus)
                ->first();

            //JP站点品类预估(备货站点品类总表)
            $areaClassifyEstimate = AreaClassifyEstimate::query()->where(['area_id' => $areaId, 'classify_id' => $classifyId])->first();
            if(!$areaClassifyEstimate) continue;

            //JP站点sku预估(备货站点sku总表)
            $areaSkuEstimate = AreaSkuEstimate::query()->firstOrNew(['area_psku'=> $areaPsku]);

            //站点备货sku(备货总表)
            $areaStockingSku = StockingSku::query()->firstOrNew(['area_psku' => $areaPsku]);
            for($i = 0; $i < AreaSkuEstimate::ESTIMATE_NUM; $i++){
                $areaSkuEstimate->{'estimate_num'.$i} = intval($skuEstimateSum->{'estimate_num'.$i});
                $areaStockingSku->{'estimate_num'.$i} = intval($skuEstimateSum->{'estimate_num'.$i});
            }
            $areaSkuEstimate->save();

            $areaStockingSku->area_id = $areaId;
            $areaStockingSku->psku_id = $_skuId;
            $areaStockingSku->classify_id = $classifyId;
            $areaStockingSku->save();
            $areaStockingSku->over_stock = StockingSku::getOverStock($areaStockingSku);
            $areaStockingSku->over_stock_value = StockingSku::getOverStockValue($areaStockingSku->over_stock,$areaStockingSku->unit_price);
            $areaStockingSku->save();

            //2.4 更新JP站点sku销售比例 (依据JP站点sku预估与JP站点品类预估,计算JP站点sku比例)
            $skuRatio = StockingSkuRatio::query()->firstOrNew(['area_psku'=> $areaPsku]);
            $classifyEstimateNum = 0;
            $skuEstimateNum = 0;
            for($i = 0; $i < AreaSkuEstimate::ESTIMATE_NUM; $i++){
                $classifyEstimateNum = intval($areaClassifyEstimate->{'estimate_num'.$i}) ?? 0; //指定参数(JP站点的品类预估数量)
                $skuEstimateNum = intval($areaSkuEstimate->{'estimate_num'.$i}) ?? 0; //指定参数(JP站点的sku预估数量)
                if($classifyEstimateNum != 0 && $skuEstimateNum != 0){
                    break;
                }
            }
            if($classifyEstimateNum != 0 && $skuEstimateNum != 0){
                $stockingSkuRatio = sprintf("%.4f", $skuEstimateNum / $classifyEstimateNum);
                $skuRatio->ratio = $stockingSkuRatio; //0.3001
                $skuRatio->save();
            }

        }

    }

}
